/*
 * Duplicate Detector Copyright (C) 2010 Marco Biscaro <marcobiscaro2112@gmail.com>
 * 
 * This file is part of Duplicate Detector.
 *
 * Duplicate Detector is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Duplicate Detector is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Duplicate Detector.  If not, see <http://www.gnu.org/licenses/>.
 */
package com.googlecode.duplicatedetector.view;

import static com.googlecode.duplicatedetector.i18n.Messages._;

import java.util.ArrayList;
import java.util.Locale;
import java.util.Map.Entry;

import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.KeyStroke;
import javax.swing.LookAndFeel;

import com.googlecode.duplicatedetector.Constants;
import com.googlecode.duplicatedetector.controller.AddFileActionListener;
import com.googlecode.duplicatedetector.controller.ChangeDebugMode;
import com.googlecode.duplicatedetector.controller.ChangeLaFActionListener;
import com.googlecode.duplicatedetector.controller.ChangeLanguageActionListener;
import com.googlecode.duplicatedetector.controller.ClearActionListener;
import com.googlecode.duplicatedetector.controller.ExitActionListener;
import com.googlecode.duplicatedetector.controller.RemoveFileActionListener;
import com.googlecode.duplicatedetector.controller.ShowHelpActionListener;
import com.googlecode.duplicatedetector.controller.StartActionListener;
import com.googlecode.duplicatedetector.i18n.Keys;
import com.googlecode.duplicatedetector.i18n.Languages;
import com.googlecode.duplicatedetector.i18n.Messages;
import com.googlecode.duplicatedetector.util.Logger;

/**
 * Menu bar used in the main window.
 * 
 * @author Marco Biscaro
 */
public class MainMenuBar extends JMenuBar implements Constants, Keys {

	private final MainPanel mainPanel;
	private static final long serialVersionUID = -3757076073913849012L;
	private JMenu fileMenu;
	private JMenuItem addMenuItem;
	private JMenuItem removeMenuItem;
	private JMenuItem clearMenuItem;
	private JMenuItem startMenuItem;
	private JMenuItem exitMenuItem;
	private JMenu languageMenu;
	private JMenu lafMenu;
	private JMenu preferencesMenu;
	private JCheckBoxMenuItem debugMenuItem;
	private JMenu helpMenu;
	private JMenuItem contentsMenuItem;
	private JMenuItem licenseMenuItem;
	private JMenuItem aboutMenuItem;

	public MainMenuBar(MainPanel mainPanel) {
		this.mainPanel = mainPanel;
		initialize();
	}

	private void initialize() {
		add(getFileMenu());
		add(getLanguageMenu());
		add(getLaFMenu());
		add(getPreferencesMenu());
		add(getHelpMenu());
	}

	private JMenu getFileMenu() {
		if (fileMenu == null) {
			fileMenu = new JMenu();
			fileMenu.setText(_(FILE));
			fileMenu.add(getAddMenuItem());
			fileMenu.add(getRemoveMenuItem());
			fileMenu.add(getClearMenuItem());
			fileMenu.addSeparator();
			fileMenu.add(getStartMenuItem());
			fileMenu.addSeparator();
			fileMenu.add(getExitMenuItem());
		}
		return fileMenu;
	}

	private JMenuItem getAddMenuItem() {
		if (addMenuItem == null) {
			addMenuItem = new JMenuItem();
			addMenuItem.setText(_(ADD));
			addMenuItem.addActionListener(new AddFileActionListener(mainPanel
					.getFileListModel(), mainPanel.getFileChooser(), this));
		}
		return addMenuItem;
	}

	private JMenuItem getRemoveMenuItem() {
		if (removeMenuItem == null) {
			removeMenuItem = new JMenuItem();
			removeMenuItem.setText(_(REMOVE));
			removeMenuItem.addActionListener(new RemoveFileActionListener(
					mainPanel.getFileListModel(), mainPanel.getFileList()));
		}
		return removeMenuItem;
	}

	private JMenuItem getClearMenuItem() {
		if (clearMenuItem == null) {
			clearMenuItem = new JMenuItem();
			clearMenuItem.setText(_(CLEAR));
			clearMenuItem.addActionListener(new ClearActionListener(mainPanel
					.getFileListModel()));
		}
		return clearMenuItem;
	}

	private JMenuItem getStartMenuItem() {
		if (startMenuItem == null) {
			startMenuItem = new JMenuItem();
			startMenuItem.setText(_(START));
			startMenuItem.addActionListener(new StartActionListener(mainPanel));
		}
		return startMenuItem;
	}

	private JMenuItem getExitMenuItem() {
		if (exitMenuItem == null) {
			exitMenuItem = new JMenuItem();
			exitMenuItem.setText(_(QUIT));
			exitMenuItem.addActionListener(new ExitActionListener(this));
		}
		return exitMenuItem;
	}

	private JMenu getLanguageMenu() {
		if (languageMenu == null) {
			languageMenu = new JMenu();
			languageMenu.setText(_(LANGUAGE));
			for (JMenuItem language : getLanguagesMenuItens()) {
				languageMenu.add(language);
			}
		}
		return languageMenu;
	}

	private ArrayList<JMenuItem> getLanguagesMenuItens() {
		ArrayList<JMenuItem> languages = new ArrayList<JMenuItem>();
		for (Entry<String, Locale> language : Languages.LANGUAGES.entrySet()) {
			languages.add(createLanguageMenuItem(language.getKey(), language
					.getValue()));
		}
		return languages;
	}

	private JMenuItem createLanguageMenuItem(String key, Locale locale) {
		/* RadioButton */JMenuItem menuItem = new /* RadioButton */JMenuItem();
		menuItem.setText(key);
		menuItem.addActionListener(new ChangeLanguageActionListener(this,
				locale));
		if (Messages.getLocale().equals(locale)) {
			menuItem.setEnabled(false);
		}
		return menuItem;
	}

	private JMenu getLaFMenu() {
		if (lafMenu == null) {
			lafMenu = new JMenu();
			lafMenu.setText(_(LOOK_AND_FEEL));
			for (JMenuItem language : getLaFMenuItens()) {
				lafMenu.add(language);
			}
		}
		return lafMenu;
	}

	private ArrayList<JMenuItem> getLaFMenuItens() {
		ArrayList<JMenuItem> lookAndFeels = new ArrayList<JMenuItem>();
		for (Entry<String, LookAndFeel> laf : LookAndFeels.LOOK_AND_FEELS
				.entrySet()) {
			lookAndFeels.add(createLaFMenuItem(laf.getKey(), laf.getValue()));
		}
		return lookAndFeels;
	}

	private JMenuItem createLaFMenuItem(String key, LookAndFeel laf) {
		JMenuItem menuItem = new JMenuItem();
		menuItem.setText(key);
		menuItem.addActionListener(new ChangeLaFActionListener(this, laf));
		return menuItem;
	}

	@Override
	public JMenu getHelpMenu() {
		if (helpMenu == null) {
			helpMenu = new JMenu();
			helpMenu.setText(_(HELP));
			helpMenu.add(getContentsMenuItem());
			helpMenu.addSeparator();
			helpMenu.add(getLicenseMenuItem());
			helpMenu.add(getAboutMenuItem());
		}
		return helpMenu;
	}

	private JMenu getPreferencesMenu() {
		if (preferencesMenu == null) {
			preferencesMenu = new JMenu();
			preferencesMenu.setText(_(PREFERENCES));
			preferencesMenu.add(getDebugMenuItem());
		}
		return preferencesMenu;
	}

	private JCheckBoxMenuItem getDebugMenuItem() {
		if (debugMenuItem == null) {
			debugMenuItem = new JCheckBoxMenuItem();
			debugMenuItem.setText(_(DEBUG));
			debugMenuItem.addActionListener(new ChangeDebugMode());
			debugMenuItem.setSelected(Logger.isDebug());
		}
		return debugMenuItem;
	}

	private JMenuItem getContentsMenuItem() {
		if (contentsMenuItem == null) {
			contentsMenuItem = new JMenuItem();
			contentsMenuItem.setText(_(CONTENTS) + "...");
			contentsMenuItem.setAccelerator(KeyStroke.getKeyStroke("F1"));
			contentsMenuItem.addActionListener(new ShowHelpActionListener(
					_(CONTENTS), Messages.getHelp(CONTENTS_FILE), this));
		}
		return contentsMenuItem;
	}

	private JMenuItem getLicenseMenuItem() {
		if (licenseMenuItem == null) {
			licenseMenuItem = new JMenuItem();
			licenseMenuItem.setText(_(LICENSE) + "...");
			licenseMenuItem.addActionListener(new ShowHelpActionListener(
					_(LICENSE), Messages.getHelp(LICENSE_FILE), this));
		}
		return licenseMenuItem;
	}

	private JMenuItem getAboutMenuItem() {
		if (aboutMenuItem == null) {
			aboutMenuItem = new JMenuItem();
			aboutMenuItem.setText(_(ABOUT) + "...");
			aboutMenuItem.addActionListener(new ShowHelpActionListener(
					_(ABOUT), Messages.getHelp(ABOUT_FILE), this));
		}
		return aboutMenuItem;
	}

}